import { shell } from "../Logger";

// 服务器返回的默认格式
export interface SimpleResult {
  success: boolean,
  message?: string,
}

// 弹窗显示服务器的返回结果
export function popSimpleResult(result: SimpleResult) {
  if (result.success) {
    shell.success(result.message ?? '程序无返回值')
  }
  else {
    shell.error(result.message ?? '程序无返回值')
    console.error(result.message)
  }
}


// 判断某个任务是否执行完毕
async function isSolved(promise: Promise<any>) {
  const t = {};
  const v = await Promise.race([promise, t])
  if (v !== t) {
    return true
  }
  else {
    return false
  }
}

class TaskManager {

  // 任务 - 一次性执行的程序
  tasks: Promise<SimpleResult>[] = []

  // 任务 - 对应任务是否结束的数组
  finished: boolean[] = []

  // 检查任务是否完成的interval
  checkInterval = 0

  // 执行代码
  public execRaw(code: string, silent = false): Promise<SimpleResult> {
    const task = apiServerExec(code)
    this.tasks.push(task)
    task.then(result => {
      if (!silent || !result.success) {
        popSimpleResult(result)
      }
    })
    this._startCheck()
    return task
  }

  public async exec(code: string, silent = false): Promise<any> {
    const result = await this.execRaw(code, silent)
    return JSON.parse(result.message!)
  }

  public async execForData(code: string, silent = false): Promise<any> {
    const result = await this.execRaw(code, silent)
    const message = JSON.parse(result.message!)
    return JSON.parse(message.value)
  }

  async _check() {
    const p_isSolvedArr = this.tasks.map((task) => isSolved(task))
    const isSovedArr = await Promise.all(p_isSolvedArr)
    this.finished = isSovedArr
    if (this.finished.every(x => x === true) && this.checkInterval !== 0) {
      window.clearInterval(this.checkInterval)
      this.checkInterval = 0
    }
  }

  _startCheck() {
    if (this.checkInterval == 0) {
      this.checkInterval = window.setInterval(() => {
        this._check()
      }, 500)
    }
  }

  public progresses: string[] = []

  public async start(code: string): Promise<SimpleResult> {
    const result = await apiServerStartProcess(code)
    this.progresses.push(result.message!)
    if (!result.success) {
      popSimpleResult(result)
    }
    return result
  }

  public async stop(id: string): Promise<SimpleResult> {
    const result = await apiServerStopProcess(id)
    if (result.success) {
      remove(this.progresses, x => x === id)
    } else {
      popSimpleResult(result)
    }
    return result
  }
}

export const defaultTaskManager = ref(new TaskManager())
